#include <string.h>

#include "bmc_control.h"
#include "gd32f4xx.h"                   // Device header
#include "pindefine.h"
#include "bsp_rcu.h"
#include "bsp_usart.h"
#include "kgl_comu.h"
#include "i2c_comu.h"
#include "systick.h"

#include "ruleBuffer.h"

#undef USE_GPU_1
#define VERSION_1_2

bmc_comu_status_data bmc_status_data;
A7_Comu a7_Comu;
uint8_t comuFlag=0;
RingBuff_t ringBuff;

void bmc_system_init(void)
{
	rcu_config();
	
	KGL_GPIO_Config();
	I2C_Init(I2C2);
}

void bmc_devices_power_on(void)
{
	delay_1ms(20);

	gpio_bit_set(LS7A_RTC_RSTN_GPIO_PORT,LS7A_RTC_RSTN_GPIO_PIN);
	delay_1ms(1);
	gpio_bit_set(EN_P1V1SB_GPIO_PORT, EN_P1V1SB_GPIO_PIN);
	delay_1ms(8);
	gpio_bit_set(LS3A_RTC_REMRSTN_GPIO_PORT,LS3A_RTC_REMRSTN_GPIO_PIN);
	gpio_bit_set(EN_P1V0_FPGA_GPIO_PORT, EN_P1V0_FPGA_GPIO_PIN);
	gpio_bit_set(EN_P5V_GPIO_PORT, EN_P5V_GPIO_PIN);
	delay_1ms(4);
	gpio_bit_set(EN_P1V2_FPGA_GPIO_PORT, EN_P1V2_FPGA_GPIO_PIN);
  gpio_bit_set(EN_P1V15_CORE_3A_GPIO_PORT, EN_P1V15_CORE_3A_GPIO_PIN);
	delay_1ms(8);
	gpio_bit_set(EN_P3V3_GPIO_PORT, EN_P3V3_GPIO_PIN);
	gpio_bit_set(EN_P3V3_IO_7A_GPIO_PORT, EN_P3V3_IO_7A_GPIO_PIN);
	gpio_bit_set(EN_P3V3_IO_3A_GPIO_PORT, EN_P3V3_IO_3A_GPIO_PIN);
	delay_1ms(1);
  gpio_bit_set(EN_P1V8_3A_GPIO_PORT, EN_P1V8_3A_GPIO_PIN);
  gpio_bit_set(EN_P1V2_HT_7A_GPIO_PORT, EN_P1V2_HT_7A_GPIO_PIN);
	delay_1ms(2);
	gpio_bit_set(EN_P1V8_HT_7A_GPIO_PORT, EN_P1V8_HT_7A_GPIO_PIN);
	gpio_bit_set(EN_P1V2_PLL_3A_GPIO_PORT, EN_P1V2_PLL_3A_GPIO_PIN);
	gpio_bit_set(EN_P1V8_PLL_3A_GPIO_PORT, EN_P1V8_PLL_3A_GPIO_PIN);
	gpio_bit_set(EN_LS7A_PLL_GPIO_PORT, EN_LS7A_PLL_GPIO_PIN);
	delay_1ms(1);
	gpio_bit_set(EN_P1V5_VDDQ_7A_GPIO_PORT, EN_P1V5_VDDQ_7A_GPIO_PIN);
	gpio_bit_set(EN_P1V5_VDDQ_3A_GPIO_PORT, EN_P1V5_VDDQ_3A_GPIO_PIN);
	delay_1ms(12);
	gpio_bit_set(EN_VDD_1V1_7A_GPIO_PORT, EN_VDD_1V1_7A_GPIO_PIN);

}

void bmc_devices_reset(void)
{
	gpio_bit_set(SATA_RST_GPIO_PORT, SATA_RST_GPIO_PIN);
	gpio_bit_set(RESET_DVI_GPIO_PORT, RESET_DVI_GPIO_PIN);

	delay_1ms(20);
//	gpio_bit_set(LS3A_RTC_REMRSTN_GPIO_PORT,LS3A_RTC_REMRSTN_GPIO_PIN);
	delay_1ms(10);
	
	gpio_bit_set(RST_FPGA_GPIO_PORT, RST_FPGA_GPIO_PIN);
	delay_1ms(500);

	gpio_bit_set(BMC_RESET_GPIO_PORT, BMC_RESET_GPIO_PIN);	
	delay_1ms(350);
	gpio_bit_set(_7A_PWR_GOOD_GPIO_PORT, _7A_PWR_GOOD_GPIO_PIN);
	
	delay_1ms(800);
	
	gpio_bit_set(CPU_PWR_GOOD_GPIO_PORT, CPU_PWR_GOOD_GPIO_PIN);
	gpio_bit_set(WORKING_STATUS_GPIO_PORT,	WORKING_STATUS_GPIO_PIN);
}

void bmc_devices_reset_disable(void)
{
	gpio_bit_reset(CPU_PWR_GOOD_GPIO_PORT, CPU_PWR_GOOD_GPIO_PIN);
	gpio_bit_reset(WORKING_STATUS_GPIO_PORT,	WORKING_STATUS_GPIO_PIN);
	
	gpio_bit_reset(RST_FPGA_GPIO_PORT, RST_FPGA_GPIO_PIN);
	gpio_bit_reset(BMC_RESET_GPIO_PORT, BMC_RESET_GPIO_PIN);
	
	gpio_bit_reset(SATA_RST_GPIO_PORT, SATA_RST_GPIO_PIN);
	gpio_bit_reset(RESET_DVI_GPIO_PORT, RESET_DVI_GPIO_PIN);

	gpio_bit_reset(_7A_PWR_GOOD_GPIO_PORT, _7A_PWR_GOOD_GPIO_PIN);
}

void bmc_device_power_down(void)
{
	reset_usart_port();
	reset_usart_memo_port();
	reset_usart_7A_port();
	
	bmc_devices_reset_disable();
	delay_1ms(300);
	
	/*切断 7a 3a3.3V*/
	gpio_bit_reset(EN_P3V3_IO_7A_GPIO_PORT, EN_P3V3_IO_7A_GPIO_PIN);
	gpio_bit_reset(EN_P3V3_IO_3A_GPIO_PORT, EN_P3V3_IO_3A_GPIO_PIN);

	delay_1ms(10);
	/*切断 公共3.3V 5V供电*/
	gpio_bit_reset(EN_P3V3_GPIO_PORT, EN_P3V3_GPIO_PIN);
	gpio_bit_reset(EN_P5V_GPIO_PORT, EN_P5V_GPIO_PIN);
	delay_1ms(10);

	/*全部重置*/
	gpio_port_write(GPIOA, 0);
	gpio_port_write(GPIOB, 0);
	gpio_port_write(GPIOC, 0);
	gpio_port_write(GPIOD, 0);
	gpio_port_write(GPIOE, 0);
	gpio_port_write(GPIOF, 0);
	gpio_port_write(GPIOG, 0);
	
	delay_1ms(5000);	//delay 5s
}

void bmc_pc_restart(void)
{
	bmc_device_power_down();
	
	init_usart_port();	
	init_usart_memo_port();
	init_usart_7A_port();
	
	bmc_devices_power_on();
	bmc_devices_reset();
}


void bmc_getAllTemperatureData(void)
{
	bmc_status_data.tempuerature_3A3000 = bmc_getTemperatureData(TEMPUARE_ADD_1);
	bmc_status_data.tempuerature_7A1000 = bmc_getTemperatureData(TEMPUARE_ADD_2);
	bmc_status_data.tempuerature_GPU    = bmc_getTemperatureData(TEMPUARE_ADD_3);
}


uint16_t bmc_getTemperatureData(uint8_t address)
{
	uint8_t wordData[2]={0};
	
	I2C_Master_Recv_Word(I2C2, address, wordData);
	uint16_t temp=(wordData[0]<<8 | wordData[1]) >> 7;
	return temp;
}

void bmc_reset_board(void)
{
	gpio_bit_reset(BMC_RESET_GPIO_PORT, BMC_RESET_GPIO_PIN);
	delay_1ms(500);
	gpio_bit_set(BMC_RESET_GPIO_PORT, BMC_RESET_GPIO_PIN);
}

float covert_lm75_2_tempature(uint16_t srcData)
{
	uint8_t sign=(srcData >> 8) & 0xFF;
	uint8_t value=(srcData & 0xFF);
	
	
	if(sign==1)
	{
		value=(~value)+1;
		return (float)(value*-0.5);
	}
	else
	{
		return (float)(value*0.5);
	}
}

uint8_t detealBoardLocation(uint8_t gaxSignal)
{	
	for(int i=0;i<5;i++)
	{
		if((gaxSignal&0x01)==0x01)
		{
			return (i+1);
		}
		else
		{
			gaxSignal>>=1;
		}
	}
	
	return 0;
}


uint8_t comuBoardCommand()
{
	if(ringBuff.Lenght>0)
	{
	if(ringBuff.Ring_Buff[ringBuff.Head] == 0x5a)
	{
		if(ringBuff.Lenght>=4)
		{
			uint8_t tempData[4]={0};
			if(RingBuf_Byte_Read(&ringBuff, tempData, 4)>0)
			{
				memcpy(&a7_Comu, tempData, 4);
				comuFlag=1;
				return 4;
			}
		}

	}
	else
	{
		uint8_t tempData=0;
		RingBuf_Byte_Read(&ringBuff, &tempData,1);
	}
}
	return 1;
}

/**
* 采集开关量，板卡位置的开关量
* 硬件逻辑为GAP，GA0~4，均接地，如果是1号位，则将GA0的直连电阻断开，此时GA0无接地信号
* BMC配置，以上6个信号分布于PE引脚组中，应采用GPIO上拉输入模式，当引脚无信号则保持高电平状态。

*
* return 返回第几个办卡号（1，5）
**/
uint8_t getBoardLocation()
{
	//采集PE引脚组的所有采集状态
	uint16_t inputStatue=gpio_input_port_get(GPIOE);
	uint8_t CPU_GAx=(uint8_t)((inputStatue & 0xFC00)>>10);
	
	return detealBoardLocation(CPU_GAx);
}

void UART3_IRQHandler(void)
{
	if(RESET!=usart_interrupt_flag_get(UART3,USART_INT_RBNEIE))
	{
		char tmpChar=usart_data_receive(UART3);
		
		RingBuf_Btye_Wrie(&ringBuff,tmpChar);
	}
}
